<template>
  <div>
    <div class="flex">
      <Button class="choose-btn" v-if="showChooseBtn" @click="showDrawer">选择</Button>
      

      <Upload :headers="uploadHeader"
            ref='uploadFile' :action="upLoadUrl" :before-upload="handleUploadIcon" :show-upload-list="showUploadList">
        
        <Button icon="ios-cloud-upload-outline" :disabled="!!loading">上传{{fileTypeName}}</Button>
      </Upload>
      <WarningTip :width="200" placement="top" class="ml10">
        <p style="white-space: normal;word-break: break-all;" v-if="!allFileType">支持上传类型:{{formatArr && formatArr.toString()}}</p>
        <p style="white-space: normal;">
          <!-- :style="{'margin-top': allFileType ? '-16px' : 0}" -->
          <!-- 文件名称:只能包含中文、英文、数字、下划线、-，名称长度为1-64个字符 -->
          文件名称:不能包含下列任意英文字符 \ / : * ? " < > |，长度为1-64个字符
        </p>
      </WarningTip>
    </div>
    
    
    
    <div class="file-list">

      <div v-if="uploadFile.name && loading">
        <div v-if="showUploadInfo" class="flex">
          <span class="mr5 mw30 text-ellipsis" :title="uploadFile.name">文件名: {{ uploadFile.name}}</span>
          <span class="mr5 mw30 text-ellipsis">文件大小：{{ fileSize }}</span>
          <span class="mw30 text-ellipsis">上传速度：{{ (speed+'')==='0'?'0kb/s':speed }}</span>
        </div>
        <Progress v-if="showUploadProgress" :percent="progress" hideInfo :stroke-width="5" style="line-height: 1;"></Progress>
      </div>
      <div v-for="item in selfFileList" :key="item.id" class="content">
        <template v-if="fileType !== 'images'">
          <Icon :type="fileType === 'docs' ? 'ios-document' : fileType === 'videos' ? 'ios-videocam' : 'logo-dropbox'" :size="16"/>
          <a v-if="download" :href="`/api/minio/download?path=${item.path}`" class="file-name">{{item.fileName}}</a>
          <div v-else class="file-name">{{item.fileName}}</div>
          <template v-if="isConfirm">
            <Poptip
                trigger="click"
                confirm
                title="确认删除吗？"
                @on-ok="delItem(item.id)">
              <Button icon="ios-trash" type="text"></Button>
            </Poptip>
          </template>
          <Button type="text" icon="ios-trash" v-else @click="delItem(item.id)"></Button>
        </template>
        <template v-else>
          <img :src="`/Learn${item.path}`"
               style="width:auto;height:40px;vertical-align: middle;"/>
          <template v-if="isConfirm">
            <Poptip
                trigger="click"
                confirm
                title="确认删除吗？"
                @on-ok="delImge(item.path)">
              <Button icon="ios-trash" type="text"></Button>
            </Poptip>
          </template>
          <Button icon="ios-trash" type="text" v-else @click="delImge(item.path)"></Button>
        </template>
      </div>
    </div>
    <DrawerPage
        select
        :title="fileTypeName"
        v-model="drawerValue"
        :columns="getShowColumns()"
        :data="list"
        :loading="loadingList"
        :total='total'
        :size.sync="query.pageSize"
        :page.sync="query.pageIndex"
        @queryFun="getMinioList"
    >
      <template slot="search">
        <Select filterable
            v-model="visibility"
            style="width:200px"
            placeholder="请选择可见范围"
            @on-change="()=>getMinioList(1)">
          <Option value="share">单位</Option>
          <Option value="public">系统</Option>
        </Select>
        <Input v-model.trim="originName" :placeholder="`${fileTypeName}名称`" style="width: 180px;" clearable @on-change="getMinioList(1)" />
        <Button class="header-btn" type="primary" ghost style="height: 32px;margin-left: 5px;" @click="refresh"><i class="el-icon-refresh-right" /></Button>
      </template>
    </DrawerPage>
  </div>
</template>

<script>
import { getFilesData } from '@/api/uploadFile.js'
export default {
  props: {
    download: {
      type: Boolean,
      default: false
    },
    showChooseBtn: {
      type: Boolean,
      default: false
    },
    formatArr: {
      type: Array,
      default: () => []
    },
    showUploadList: {
      type: Boolean,
      default: false
    },
    fileType: {
      type: String,
      default: 'files'
    },
    btnTxt:{
      type: String,
      default: '文件'
    },
    fileList: {
      type: Array,
      default: () => []
    },
    isSingle: {
      type: Boolean,
      default: false
    },
    allFileType: {
      type: Boolean,
      default: false
    },
    isConfirm: {
      type: Boolean,
      default: true
    },
    showUploadProgress:{ //是否显示上传进度
      type: Boolean,
      default: true
    },
    showUploadInfo:{ //是否显示上传信息
      type: Boolean,
      default: true
    },
    bucket:{
      type: String,
      default: ''
    },
    Unlimited:{
      type: Boolean,
      default: false
    }
  },
  computed: {
    fileTypeName() {
      if(this.btnTxt){
        return this.btnTxt
      }else{
        if(this.fileType){
          switch(this.fileType) {
            case 'docs': return '文档'
            case 'videos': return '视频'
            case 'files': return '工具'
            case 'images': return '图片'
          }
        }
      }
    },
    filePaths() {
      return this.selfFileList.map(item => item.path)
    }
  },
  watch: {
    fileList(list) {
      this.selfFileList = [].concat(list)
    },
    loading(val){ //外层modal的确定按钮可能需要控制
      this.$emit('upload-loading',val)
    }
  },
  mounted() {
    this.selfFileList = [].concat(this.fileList)
    // this.setStyle()
    // window.addEventListener('resize', this.setStyle)
  },
  beforeDestroy() {
    this.cancelUpload()
    // window.removeEventListener('resize', this.setStyle)
  },
  data() {
    return {
      flag: 0, //标记分片上传成功的次数
      filedArr: [],//承装切片的容器
      USER_ID: '',
      columns: [{
        title: '名称',
        key: 'originName',
        align: 'center',
        tooltip: true
      }, {
        title: '缩略图',
        key: 'path',
        align: 'center',
        render: (h, params) => {
          return h('img', {
            attrs: {
              src: this.handleImage(params.row.path)
            },
            style: {
              display: 'inline-block',
              maxHeight: '40px',
              width: 'auto',
              verticalAlign: 'middle'
            }
          })
        }
      },
        {
          title: '可见范围',
          key: 'visibility',
          width: 100,
          align: 'center',
          render: (h, params) => {
            return h('div', {
              style: {
                color: this.handlePublic(params.row.visibility).color
              }
            }, this.handlePublic(params.row.visibility).text)
          }
        },{
          title: '内容',
          key: 'check',
          align: 'center',
          width: 100,
          render: (h, params) => {
            return h('div', [
              h('a', {
                on: {
                  click: () => {
                    this.checkInfo(params);
                  }
                }
              }, '查看')
            ]);
          }
        }, {
          title: '创建者',
          key: 'creatorName',
          align: 'center',
          tooltip: true
        }, {
          title: '创建时间',
          key: 'created',
          align: 'center',
          tooltip: true
        }, {
          title: '操作',
          key: 'action',
          width: 100,
          align: 'center',
          render: (h, params) => {
            let text = ''
            if(params.row.isUsed) {
              text = '已用'
            } else {
              text = '使用'
            }
            return h('a', {
              style: {
                color: params.row.isUsed ? '#2f70ff' : 'grey',
                cursor: 'pointer'
              },
            }, [
              h('div', {
                on: {
                  'click': () => {
                    this.chooseImg(params)
                  },
                },
              }, [
                h('img', {
                  attrs: {
                    src: params.row.isUsed ? require('../../assets/globalIcon/choosed.png') : require('../../assets/globalIcon/add.png'),
                  },
                  style: {
                    'margin-right': '5px',
                    'vertical-align': 'middle',
                    width: '16px',
                    height: '16px',
                    display: 'inline-block',
                  },
                }),
                h('span', {}, text)
              ])
            ])
          }
        },
      ],
      loadingList: false,
      drawerValue: false,
      query: {
        pageIndex: 1,
        pageSize: 10
      },
      list: [],
      total: 0,
      visibility:'company',
      originName: '',
      uploadHeader: {
        Authorization: localStorage.token,
        Accept: '*/*'
      },
      selfFileList: [],
      speed: 0,
      loaded: 0,
      progress: 0,
      fileSize:0,
      loading:false,
      isUpdataing:false, //判断是否在上传中
      uploadAction: `${this.baseURL}minio/upload/merge/file`,
      upLoadUrl: `${this.baseURL}/minio/upload/part`,
      showSelectBucket:false, //是否需要选择桶
      uploadFile:{}, //当前上传文件信息，包括了speed.progress等
      uploadList:[]
    }
  },
  computed: {
    fileTypeName() {
      switch(this.fileType) {
        case 'docs': return '文档'
        case 'videos': return '视频'
        case 'files': return '工具'
        case 'images': return '图片'
      }
    },
    filePaths() {
      return this.selfFileList.map(item => item.path)
    }
  },
  watch: {
    fileList(list) {
      this.selfFileList = [].concat(list)
    },
    loading(val){ //外层modal的确定按钮可能需要控制
      this.$emit('upload-loading',(!!val))
    }
  },
  mounted() {
    this.selfFileList = [].concat(this.fileList)
    // this.setStyle()
    // window.addEventListener('resize', this.setStyle)
  },
  beforeUpdate(){

  },
  beforeDestroy() {
    this.cancelUpload()
    // window.removeEventListener('resize', this.setStyle)
  },
  methods: {
    chooseImg(params) {
      let template = this.list.find(item => item.id === params.row.id)
      if (params.row.isUsed) {
        if (template) {
          this.$set(template, 'isUsed', false)
        }
        if (this.fileType !== 'images') {
          this.$emit('del-item-fildId', params.row.id)
        } else {
          this.delImge()
        }
        return
      }
      if (template) {
        if (this.isSingle) { // 单选模式，需要将其他的选中项全部设置为未选
          this.list.forEach(item => this.$set(item, 'isUsed', false))
        }
        this.$set(template, 'isUsed', true)
      }
      this.$emit('upload-success', {
        fileId: params.row.id,
        filePath: params.row.path,
        fileName: params.row.originName
      })
    },
    checkInfo(params) {
      let path = params.row.path;
      if(params.row.originName.endsWith('.md')){
        let href = this.$router.resolve({
          name:'mdPreview',
          query:{
            path:path,
            name:params.row.originName
          }
        }).href;
        window.openTrain(href,'_blank')
      }else{
        window.openTrain(`/api/minio/filePreview?path=${path}`);
      }
    },
    handlePublic(val){
      let obj = {
        text:'',
        color:'#8d95a6'
      }
      switch (val){
        case 'person':
        case 0:
        case '0':
          return obj = {
            text:'个人',
            color:'rgb(255, 165, 0)',
          }
          break;
        case 'company':
        case 1:
        case '1':
          return obj = {
            text:'单位',
            color:'rgb(50, 205, 50)',
          }
          break;
        case 'system':
        case 2:
        case '2':
          return obj = {
            text:'系统',
            color:'rgb(65, 105, 225)',
          }
          break;
        case 'range':
        case 3:
        case '3':
          return obj = {
            text:'平台',
            color:'#ff61f4',
          }
          break;
      }
    },
    handleImage(logo) {
      let src = ''
      if(logo) {
        if(logo.indexOf('Learn') > -1) {
          src = logo
        } else {
          src = `/Learn/${logo}`
        }
      } else {
        src = this.defaultImg
      }
      return src
    },
    getShowColumns() {
      if(this.fileType != 'images') {
        return this.columns.filter(col => col.key != 'path');
      } else {
        return this.columns;
      }
    },
    refresh() {
      this.query.pageIndex = 1
      this.originName = ''
      this.getMinioList()
    },
    // 设置高度
    setStyle() {
      window.fullHeight = document.documentElement.clientHeight;
      window.fullWidth = document.documentElement.clientWidth;
      this.fullHeight = window.fullHeight;
      this.fullWidth = window.fullWidth;
      this.contentHei = this.fullHeight - 60 - 21 + 'px' // 80是头部高度  60是上下padding
      this.setUserTableHei = this.fullHeight - 212
      this.query.pageSize = Math.floor(this.setUserTableHei / 50) - 1
    },
    getMinioList(pageIndex) {
      this.query.pageIndex = pageIndex || 1
      this.loadingList = true
      getFilesData(this.query, {
        bucket: this.fileType,
        originName: this.originName,
        visibility: this.visibility
      }).then(({ data = {} }) => {
        let { code, message } = data
        if (code !== 1) {
          this.$Message.warning(message)
          this.list = []
          this.total = 0
          return
        }
        data = data.data || {}
        this.list = (data.list || []).map(item => {
          item.isUsed = this.filePaths.includes(item.path)
          return item
        })
        this.total = data.total
      }).finally(() => {
        this.loadingList = false
      })
    },
    showDrawer() {
      this.refresh()
      this.drawerValue = true
      this.getMinioList()
    },
    delItem(id) {
      this.$emit('del-item', id)
    },
    delImge(path) {
      this.$emit('del-image', path)
    },
    // 上传图片成功后的回调函数，获取图片上传后的保存的位置，用于回显图片
    getFileUrl(res) {
      if (res.code == 1) {
        this.$emit('upload-success', {
          fileId: res.info.id,
          filePath: res.data,
          fileName: res.info.originalName,
          size:res.info.size
        })
      } else {
        this.$Message.error('文件上传失败')
      }
      this.loading = false;
      this.uploadFile = {};
      this.uploadList = [];
    },
    getFileName (name) {
      return name.substring(0, name.lastIndexOf("."))
    },
    cancelUpload(){ //取消上传
      this.$refs.uploadFile.clearFiles()
      // this.source && this.source.cancel('cancelUpload'); //需要请求接口上传就放出来，手动ajax上传有效
      // this.source = '';
      this.uploadFile = {};
      this.loading = false;
    },


    
    upload (file) {
      if (file.size <= 0) {
        this.$Message.error({
          content: '无效文件!',
          duration: 3
        })
        return
      }
    
      this.filedArr = []
      var clientId = this.generateClientId() //id
      var fileName = file.name;
      var size = file.size
      // if (file.size < 1024 * 1024 * 600) {
      // var shardSize = file.size; //如果上传的文件小于600M直接以当前文件为一个分片
      // } else {
      var shardSize = 1024 * 1024 * 50; //如果上传的文件大于600M就以50M为一个分片
      // }
      var chunks = Math.ceil(size / shardSize); //总片数
      for (var i = 0; i < chunks; ++i) {
        var start = i * shardSize; //计算每一片的起始位置
        var end = Math.min(size, start + shardSize)  //计算每一片的结束位置
        var partFile = file.slice(start, end)
        this.filedArr.push(partFile)
      };
      //上传分片请求函数
      const partUpload = async (clientId, filedArr, chunks, chunkId) => {
        try {
          let _this = this
          let partFile = filedArr[chunkId]
          var form = new FormData();
          form.append('clientId', clientId); //客户端id
          form.append('file', partFile); // slice方法 用于切出文件的一部分
          // form.append('fileName', fileName); // 文件名
          // form.append('chunks', chunks); // 总片数
          form.append('chunkId', chunkId); //当前是第几片
          const res = await _this.axios({
            method: 'post',
            url: `${this.baseURL}/minio/upload/part`,
            data: form,
            headers: {
              'Content-type': 'multipart/form-data',
            },
            timeout:0,
            onUploadProgress: progressEvent => {

              this.fileSize = this.getFileSize(file.size)
              
              this.fileName = file.name
              
              let hasUpload = chunkId*shardSize // 已经上传的分片 大小
              var complete = Math.floor((hasUpload+progressEvent.loaded) / file.size * 100)
              _this.progress = complete
              // console.log(`第${chunkId}片，已经上传${hasUpload},当前片大小${progressEvent.loaded},文件总`,file.size)
              
              var newTime = +new Date()
              var DTime = (newTime - this.oldTime) / 1000
              this.oldTime = newTime

              let loadingValue = _this.loading===false?0:_this.loading
              var aaspeed = Number(progressEvent.loaded - loadingValue) / (1024 * 1024)
              _this.loading = progressEvent.loaded
              if (aaspeed / DTime < 1) {
                _this.speed = (Math.round(aaspeed / DTime * 1024 * 100) / 100).toString() + 'kB/s'
              } else {
                _this.speed = (Math.round(aaspeed / DTime * 100) / 100).toString() + 'MB/s'
              }

              if(_this.speed.includes('NaN') || (_this.speed+'') === '0') {
                _this.speed ='0 kB/s'
              }
              
              
              
            },
          });
          if (res.data.code == 1) {
            chunkId += 1
            if (chunkId < this.filedArr.length) {
              _this.loading = 0
              this.flag += 1
              var complete = Math.ceil(this.flag / chunks * 100)   //当前进度所占总进度的百分比
              this.progress = complete
              partUpload(clientId, this.filedArr, chunks, chunkId)
            } else {
              this.flag += 1
              var complete = Math.ceil(this.flag / chunks * 100)   //当前进度所占总进度的百分比
              this.progress = complete
              if (this.progress == 100) {
                this.setDisabled = false //打开提交和选择文件按钮权限
              
                this.speed = 0//置空速度
                this.flag = 0
                this.filedArr = []
                this.flag = 0

                //console.log('---分片文件上传成功!几片：',chunks)
                this.mergeFile(clientId,fileName) //不再调用合并分片接口，创建镜像的时候tempId为随机生成的clientId
                // this.imageFormData.tempId = clientId
              }
            }
          }
        } catch (error) {
          this.$Message.error('上传文件出错')
          console.log(error)
        }

      }
      partUpload(clientId, this.filedArr, chunks, 0)
    },
    mergeFile(clientId,fileName){
      console.log(fileName,111111);

      let url = this.uploadAction + `&clientId=${clientId}&sourceName=${fileName}`
      console.log(url)
      this.axios({
        method:'post',
        url:url,
        headers:{
          'Content-type': 'multipart/form-data'
        },
        timeout:0,
      }).then(({ data = {} }) => {
        if(data.code == 1) {
          let file = data;
          this.getFileUrl(file)


          console.log('上传文件---合并文件成功')
          this.$Message.success('上传文件成功')
        } else {
          this.$Message.warning(data.message);
          this.formItem.file=null
        }
        this.loading = false
        console.log(data,11111111111);
      }).catch((err) => {
        this.$Message.error('合并文件出错')
        console.log(err,'errerrerrerrerr')
      }).finally(() => {
        this.loading = false
      })
    },
    generateClientId () {
      var counter = 0;
      var clientId = (+new Date()).toString(32),
          i = 0;
      for (; i < 5; i++) {
        clientId += Math.floor(Math.random() * 65535).toString(32);
      }
      return clientId + (counter++).toString(32);
    },

    handleUploadIcon(file,a,b){

      this.speed = 0;
      this.loading = 0;
      this.progress = 0;
      this.isUpdataing = true
      this.onlyFileName = file.name + '_' + new Date().getTime();
      this.uploadFile = {};
      if (file) {
        this.fileSize = this.getFileSize(file.size);
        //验证名称
        if(file.name){
          let name = this.getFileName(file.name);
          // let reg = new RegExp("^[\u4E00-\u9FA5a-zA-Z0-9_ -]*$");
          let reg = new RegExp('/[\\/:*?"<>|]/gi');
          if (reg.test(name) || name.length > 64) {
            this.$Message.warning('文件名不能包含下列任意英文字符 \ / : * ? " < > |，长度为1-64个字符')
            return false;
          }
        }
      }
      let exceededNum=file.name.lastIndexOf(".");
      let exceededStr=file.name.substring(exceededNum+1,file.name.length).trim().toLowerCase();
      this.loading = true;
      if (!this.allFileType) { // 如果不是全部的类型都可以上传的话，判断一下上传类型
        let formatArr = this.formatArr+''
        if (!formatArr.includes(exceededStr) ) {
          this.$Message.warning('不支持当前文件类型')
          this.loading = false;
          return false
        }
      }
       // 所有文件均可上传，自动识别文件类型，手动调用上传
        this.uploadFile = file;
        let imageArr = ["jpeg","jpg","jpe","png","gif","tiff","bmp","dwg","psd","ico","rgb","ogx","pcx","mdi","tif","pgm","cmx","webp"];
        let docsArr = ["pdf","doc","docx","xls","xlsx","xla","pptx","pps","ppt","rtf","txt","md"];
        let othersArr = ["zip","bz2","7z","cab","rar","epub"];
        let videoArr = ["mp4","webm","ogv","ogg","3gp","3g2","m4v","mpg","vob","fli","mkv","asf","asx","wmv","flv","avi"];
        let audioArr = ["m4a","sil","ra","ram","au","wma","aiff","mp3","mid","midi","rmi","oga","wav","caf","flac","adp","aac"];
        let action = '',bucket = '';
        let uploadAction = `/api/minio/upload/merge/file` // `/api/minio/upload/merge/file`    /api/minio/upload/permanent
        if(imageArr.includes(exceededStr)){
          bucket = this.bucket || 'images';
          action = `${uploadAction}?visibility=company&bucket=${bucket}&type=images`
        }else if(docsArr.includes(exceededStr)){
          bucket = this.bucket || 'docs';
          action = `${uploadAction}?visibility=company&bucket=${bucket}&type=docs`
        }else if(othersArr.includes(exceededStr)){
          bucket = this.bucket || 'files';
          action = `${uploadAction}?visibility=company&bucket=${bucket}&type=files`
        }else if(videoArr.includes(exceededStr)){
          bucket = this.bucket || 'videos';
          action = `${uploadAction}?visibility=company&bucket=${bucket}&type=videos`
        }else if(audioArr.includes(exceededStr)){
          bucket = this.bucket || 'audios';
          action = `${uploadAction}?visibility=company&bucket=${bucket}&type=audios`
        }else if(exceededStr == 'glb'){
          bucket = this.bucket || 'relay';
          action = `${uploadAction}?visibility=company&bucket=${bucket}&type=glb`
        }else{
          bucket = this.bucket || 'files';
          action = `${uploadAction}?visibility=company&bucket=${bucket}&type=files`
        }
        this.uploadAction = action;

        this.upload(file)
        return  false

      
    },

    getFileSize(size) {
      let fileSize;
      if(size > 1024 * 1024) {
        fileSize = (Math.round(size * 100 / (1024 * 1024)) / 100).toString() + 'MB'
      } else {
        fileSize = (Math.round(size * 100 / 1024) / 100).toString() + 'KB'
      }
      return fileSize;
    },
  }
}
</script>

<style scoped>
.choose-btn {
  float: left;
  margin: 1px 6px 0 0;
}

.file-list {
  max-height: 132px;
  overflow: auto;
  width: 100%;
}

.file-list>.content {
  display: flex;
  align-items: center;
  margin: 6px;
  justify-content: space-between;
  background: var(--table-tr-hover-color);
}

.file-list .file-name {
  flex: 1;
  margin-left: 6px;
}

.file-list /deep/ button {
  border: none !important;
}

.file-list /deep/ button i {
  font-size: 16px;
  color: #ed4014;
}
.mr5{
  margin-right:5px;
}
.mw30{
  max-width: calc(33% - 5px);
}
.flex{
  display: flex;
}
</style>